
#include <stdlib.h>
#include <string.h>
#include "circular-linked-list.h"

int InitList(CrcList *List){
    List->list_head = NULL;
    List->list_length = 0;
    return(0);
}


int ListEmpty(CrcList List){
    if (List.list_head == NULL && List.list_length == 0){
        return(1);
    } else if (List.list_head == NULL || List.list_length == 0){
        return(-1);
    } else{
        return(0);
    }
}


int ClearList(CrcList *List){

    if (List == NULL || List->list_head == NULL || List->list_length ==0){
        return(-1);
    }

    CrcLiNode *p_current = List->list_head,*tmp;
    while (p_current->next_node != List->list_head){
        tmp = p_current->next_node;
        free(p_current);
        p_current = tmp;
        --List->list_length;
    }

    List->list_head = NULL;
    return((int)List->list_length);
}


int GetElem(CrcList List,unsigned int i,ElemType *e){
    if (i == 0 || i > List.list_length) {
        return (-1);
    }else{
        CrcLiNode *p_current = List.list_head;
        for (int j = 1; j < i; ++j) {
            p_current = p_current->next_node;
        }
        memcpy(e,&p_current->node_data, sizeof(ElemType));
        return(0);
    }
}

int LocateElem(CrcList List,ElemType e){
    if (List.list_head == NULL || List.list_length == 0){
        return(-1);
    }else{
        int location = 1;
        CrcLiNode *p_current = List.list_head;
        while (p_current->next_node != List.list_head){
            if (memcmp(&p_current->node_data,&e, sizeof(ElemType)) == 0){
                return location;
            }
            p_current = p_current->next_node;
            ++location;
        }
        return(0);
    }
}

int ListInsert(CrcList *List,unsigned int i,ElemType e){
    CrcLiNode *p_current = List->list_head;
    if (i == 0){
        return(-1);
    }else if(i == 1 && List->list_head == NULL){
        List->list_head = malloc(sizeof(CrcLiNode));
        List->list_head->next_node = List->list_head;
        memcpy(&List->list_head->node_data,&e, sizeof(ElemType));
        ++List->list_length;
        return(0);
    }else if(i == 1 && List->list_head != NULL){
        while (p_current->next_node != List->list_head) {
            p_current = p_current->next_node;
        }
        p_current->next_node = malloc(sizeof(CrcLiNode));
        p_current = p_current->next_node;
        memcpy(&p_current->node_data,&e, sizeof(ElemType));
        ++List->list_length;
        p_current->next_node = List->list_head;
        List->list_head = p_current;
        return(0);
    }else{
        if (List->list_head == NULL && List->list_length == 0){
            List->list_head = malloc(sizeof(CrcLiNode));
            memset(&List->list_head->node_data,0, sizeof(ElemType));
            List->list_head->next_node = List->list_head;
            ++List->list_length;
            p_current = List->list_head;
        }
        for (int j = 2; j < i; ++j) {
            if (p_current->next_node == List->list_head){
                p_current->next_node = malloc(sizeof(CrcLiNode));
                memset(&p_current->next_node->node_data,0, sizeof(ElemType));
                p_current->next_node->next_node = List->list_head;
                ++List->list_length;
            }
            p_current = p_current->next_node;
        }
        CrcLiNode *tmp = p_current->next_node;
        p_current->next_node = malloc(sizeof(CrcLiNode));
        memcpy(&p_current->next_node->node_data,&e, sizeof(ElemType));
        p_current->next_node->next_node = tmp;
        ++List->list_length;
        return(0);
    }

}
int ListDelete(CrcList *List,unsigned int i,ElemType *e){
    CrcLiNode *p1 = List->list_head,*p2;
    if (i == 0 || i > List->list_length){
        return(-1);
    }
    p2 = p1->next_node;
    for (int j = 2; j < i; ++j) {
        p1 = p1->next_node;
        p2 = p2->next_node;
    }
    p1->next_node = p2->next_node;
    free(p2);
    --List->list_length;
    return(0);
}
